fn main() {
    // 1. 原始指针
    let mut num = 1;
    let c1 = &mut num as *mut i32;
    // 注意, 这里是&num, 不是num
    let c2 = &num as *const i32;
    println!("c1: {:?}, c2: {:?}", c1, c2);
    // 只能在unsafe块中解引用
    unsafe {
        println!("unsafe, c1: {}, c2: {}", *c1, *c2);
    }

    // 2. 地址
    let b = 0x123456usize;
    let p = &b as *const usize;

    #[warn(unused_unsafe)]
    unsafe {
        println!("p: {:?}", p);
    }
    // 3. unsafe 函数
    unsafe fn unsafe_fn() {
        println!("this is not safe")
    }

    // 只能在unsafe中执行unsafe函数
    unsafe {
        unsafe_fn()
    }

    // 4.
    let mut v = vec![1,2,3,4,5,6];
    let vp = &mut v[..];
    let (start, end) = v.split_at_mut(3);
    assert_eq!(start, &mut [1,2,3]);
    assert_eq!(end, &mut [4,5,6]);
    println!("this is ok");

    // 注意, 这里的mid是unsize类型, 因为slice.len()返回值是unsize;
    // fn split_at_mut(slice: &mut[i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    //     let len = slice.len();
    //     assert!(mid <= len);
    //     (&mut slice[..mid], &mut slice[mid..])
    // }
    use std::slice;
    fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
        let len = slice.len();
        assert!(mid <= len);
        // ptr为指向切片第一个元素的原始、未加工的可变指针。
        let ptr = slice.as_mut_ptr();
        unsafe {
            (
                slice::from_raw_parts_mut(ptr, mid),
                slice::from_raw_parts_mut(ptr.add(mid), len - mid)
            )
        }
    }
    let mut v2 = vec![1,2,3,4,5,6];
    let (one, two) = split_at_mut(&mut v2, 3);
    println!("one: {:?}, two: {:?}", one, two);
}